package com.fishingwithme.controllers;

import com.fishingwithme.domain.user.SpotUser;
import com.fishingwithme.domain.user.UsernamePasswordService;
import com.fishingwithme.infrastructure.dtos.DTO;
import com.fishingwithme.infrastructure.dtos.RegisterRequest;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/user")
@Tag(name = "Authentication", description = "User authentication and registration APIs")
public class AuthController {

    @Autowired
    private UsernamePasswordService usernamePasswordService;

    @PostMapping("/register")
    @Operation(
            summary = "Register new user",
            description = "Register a new user account with username, password, email and nickname"
    )
    @ApiResponses(value = {
            @ApiResponse(
                    responseCode = "200",
                    description = "User registered successfully",
                    content = @Content(
                            mediaType = "application/json",
                            schema = @Schema(implementation = DTO.class)
                    )
            ),
            @ApiResponse(
                    responseCode = "400",
                    description = "Invalid input parameters or user already exists",
                    content = @Content(
                            mediaType = "application/json",
                            schema = @Schema(implementation = DTO.class)
                    )
            ),
            @ApiResponse(
                    responseCode = "500",
                    description = "Internal server error during registration",
                    content = @Content(
                            mediaType = "application/json",
                            schema = @Schema(implementation = DTO.class)
                    )
            )
    })
    public @ResponseBody DTO<SpotUser> register(
            @Parameter(description = "User registration information", required = true)
            @RequestBody RegisterRequest request) {
        if (request.getUsername() == null || request.getUsername().trim().isEmpty()) {
            return DTO.fail("用户名不能为空");
        }
        if (request.getUsername().length() < 3 || request.getUsername().length() > 20) {
            return DTO.fail("用户名长度必须在3-20个字符之间");
        }
        if (request.getPassword() == null || request.getPassword().trim().isEmpty()) {
            return DTO.fail("密码不能为空");
        }
        if (request.getPassword().length() < 6 || request.getPassword().length() > 20) {
            return DTO.fail("密码长度必须在6-20个字符之间");
        }

        if (usernamePasswordService.existsByUsername(request.getUsername())) {
            return DTO.fail("用户名已存在");
        }

        try {
            SpotUser registeredUser = usernamePasswordService.registerUser(
                request.getUsername(), 
                request.getPassword(), 
                request.getEmail(), 
                request.getNickname()
            );
            return DTO.success(registeredUser);
        } catch (IllegalArgumentException e) {
            return DTO.fail(null, 400, e.getMessage());
        } catch (Exception e) {
            return DTO.fail(null, 500, "注册失败");
        }
    }

    @GetMapping("/check-username")
    @Operation(
            summary = "Check username availability",
            description = "Check if a username is available for registration"
    )
    @ApiResponses(value = {
            @ApiResponse(
                    responseCode = "200",
                    description = "Username availability check completed",
                    content = @Content(
                            mediaType = "application/json",
                            schema = @Schema(implementation = DTO.class)
                    )
            )
    })
    public @ResponseBody DTO<Boolean> checkUsername(
            @Parameter(description = "Username to check availability", required = true, example = "fisherman123")
            @RequestParam String username) {
        boolean exists = usernamePasswordService.existsByUsername(username);
        return DTO.success(!exists);
    }
}